import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './draw.css';

const Tool = ({id, imgSrc, title, selected, onClick, index}) => {
    return <li id={id} style={{ background: selected ? "yellow" : "#ccc" }} onClick={() => onClick(index)}><img src={require("./" + imgSrc)} alt="" title={title}/></li>
}

const Shape = ({id, imgSrc, selected, onClick, index}) => {
    return <li id={id} style={{ background: selected?"yellow":"#ccc" }} onClick={() => onClick(index)}><img src={require("./" + imgSrc)} alt=""/></li>
}

const Size = ({id, imgSrc, selected, onClick, index}) => {
    return <li id={id} style={{ background: selected?"yellow":"#ccc" }} onClick={() => onClick(index)}><img src={require("./" + imgSrc)} alt=""/></li>
}

const Color = ({color, selected, onClick, index}) => {
    return <li id={color} style={{ border: selected?"3px solid crimson":"3px solid #fff" }} onClick={() => onClick(index)}></li>
}

const drawLine = (ctx, startX, startY, moveX, moveY, lineWidths, col) => {
    ctx.save();
    ctx.beginPath();
    ctx.moveTo(startX, startY);
    ctx.lineTo(moveX, moveY);
    ctx.closePath();
    ctx.lineWidth = lineWidths;
    ctx.strokeStyle = col;
    ctx.stroke();
    ctx.restore();
}

const drawCircle = (ctx, startX, startY, moveX, moveY, lineWidths, col) => {
    ctx.save();
    ctx.beginPath();
    const a = moveX - startX;
    const b = moveY - startY;
    const c = Math.sqrt(a * a + b * b);
    ctx.arc(startX, startY, c, 0, 2 * Math.PI, false);
    ctx.closePath();
    ctx.lineWidth = lineWidths;
    ctx.strokeStyle = col;
    ctx.stroke();
    ctx.restore();
}

const fillCircle = (ctx, startX, startY, moveX, moveY, lineWidths, col) => {
    ctx.save();
    ctx.beginPath();
    const a = moveX - startX;
    const b = moveY - startY;
    const c = Math.sqrt(a * a + b * b);
    ctx.arc(startX, startY, c, 0, 2 * Math.PI, false);
    ctx.closePath();
    ctx.lineWidth = lineWidths;
    ctx.fillStyle = col;
    ctx.fill();
    ctx.restore();
}

const drawRect = (ctx, startX, startY, moveX, moveY, lineWidths, col) => {
    ctx.save();
    ctx.lineWidth = lineWidths;
    ctx.strokeStyle = col;
    const a = Math.abs(moveX - startX);
    const b = Math.abs(moveY - startY);
    if (moveX > startX && moveY > startY) {
        ctx.strokeRect(startX, startY, a, b);
    } else if (moveX > startX && moveY < startY) {
        ctx.strokeRect(startX, startY - b, a, b);
    } else if (moveX < startX && moveY < startY) {
        ctx.strokeRect(moveX, moveY, a, b);
    } else {
        ctx.strokeRect(moveX, moveY - b, a, b);
    }
    ctx.restore();
}

const fillRect = (ctx, startX, startY, moveX, moveY, lineWidths, col) => {
    ctx.save();
    ctx.lineWidth = lineWidths;
    ctx.fillStyle = col;
    const a = Math.abs(moveX - startX);
    const b = Math.abs(moveY - startY);
    if (moveX > startX && moveY > startY) {
        ctx.fillRect(startX, startY, a, b);
    } else if (moveX > startX && moveY < startY) {
        ctx.fillRect(startX, startY - b, a, b);
    } else if (moveX < startX && moveY < startY) {
        ctx.fillRect(moveX, moveY, a, b);
    } else {
        ctx.fillRect(moveX, moveY - b, a, b);
    }
    ctx.restore();
}

const drawTriangle = (ctx, startX, startY, moveX, moveY, lineWidths, col) => {
    ctx.save();
    ctx.beginPath();
    if (moveX > startX && moveY > startY) {
        ctx.moveTo(startX, startY);
        ctx.lineTo(moveX, moveY);
        ctx.lineTo(2 * startX - moveX, moveY);
    } else if (moveX < startX && moveY > startY) {
        ctx.moveTo(startX, startY);
        ctx.lineTo(moveX, moveY);
        ctx.lineTo(2 * startX - moveX, moveY);
    } else if (moveX > startX && moveY < startY) {
        ctx.moveTo(startX, startY);
        ctx.lineTo(moveX, moveY);
        ctx.lineTo(2 * moveX - startX, startY);
    } else {
        ctx.moveTo(startX, startY);
        ctx.lineTo(moveX, moveY);
        ctx.lineTo(2 * moveX - startX, startY);
    }
    ctx.closePath();
    ctx.lineWidth = lineWidths;
    ctx.strokeStyle = col;
    ctx.stroke();
    ctx.restore();
}

const drawText = (ctx, startX, startY, col, text) => {
    ctx.save();
    ctx.font = "bold 14px Arial";
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillStyle = col;
    ctx.fillText(text, startX, startY);
    ctx.restore();
}

class MyDraw extends Component {

    constructor (props) {
        super(props)
        this.state = {
            tools: [
                {id: "means_brush", imgSrc: "imgs/Brush.png", title: "画笔", selected: true},
                {id: "means_eraser", imgSrc: "imgs/Eraser.png", title: "橡皮", selected: false},
                {id: "means_paint", imgSrc: "imgs/Paint.png", title: "喷漆", selected: false},
                {id: "means_straw", imgSrc: "imgs/Straw.png", title: "吸管", selected: false},
                {id: "means_text", imgSrc: "imgs/text.png", title: "文字", selected: false},
                {id: "means_magnifier", imgSrc: "imgs/Magnifier.png", title: "放大镜", selected: false},],
            shapes: [
                {id: "means_line", imgSrc: "imgs/line.png", selected: false},
                {id: "means_arc", imgSrc: "imgs/arc.png", selected: false},
                {id: "means_rect", imgSrc: "imgs/rect.png", selected: false},
                {id: "means_poly", imgSrc: "imgs/poly.png", selected: false},
                {id: "means_arcfill", imgSrc: "imgs/arcfill.png", selected: false},
                {id: "means_rectfill", imgSrc: "imgs/rectfill.png", selected: false}
            ],
            sizes: [
                {id: "width_1", imgSrc: "imgs/line1px.png", selected: true},
                {id: "width_3", imgSrc: "imgs/line3px.png", selected: false},
                {id: "width_5", imgSrc: "imgs/line5px.png", selected: false},
                {id: "width_7", imgSrc: "imgs/line7px.png", selected: false}
            ],
            colors: [
                "red", "green", "blue", "yellow", "white", "black", "pink", "purple", "cyan", "orange"
            ].map((color, index) => {
                return {color: color, selected: index === 5}
            }),
            startX: 0,
            startY: 0,
            moveX: 0,
            moveY: 0,
            upX: 0,
            upY: 0,
            flag: 0,
            accord: [],
        }
        this.handleClickClear = this.handleClickClear.bind(this);
        this.handleClickSave = this.handleClickSave.bind(this);
        this.handleClickTool = this.handleClickTool.bind(this);
        this.handleClickShape = this.handleClickShape.bind(this);
        this.handleClickSize = this.handleClickSize.bind(this);
        this.handleClickColor = this.handleClickColor.bind(this);
        this.handleCanvasMouseDown = this.handleCanvasMouseDown.bind(this);
        this.getCurrentPicProps = this.getCurrentPicProps.bind(this);
        this.againDraw = this.againDraw.bind(this);
        this.handleCanvasMouseUp = this.handleCanvasMouseUp.bind(this);
        this.handleCanvasMouseOut = this.handleCanvasMouseOut.bind(this);
        this.handleCanvasMouseMove = this.handleCanvasMouseMove.bind(this);
    }
    // componentDidMount () {
    //     const canvas = ReactDOM.findDOMNode(this.refs.myCanvas);

    //     let ctx = canvas.getContext('2d');
    //     this.setState({
    //         ctx
    //     });

    //     ctx.font = "30px Courier New";

    //     ctx.strokeStyle = "red";
    //     ctx.strokeText("奔跑吧，兄弟！", 50, 50);
    // }

    /**
     * 保存画布
     */
    handleClickSave() {
        const canvas = ReactDOM.findDOMNode(this.refs.myCanvas);
        const image = new Image();
        image.src = canvas.toDataURL("image/png");
        console.log(image);
    }

    /**
     * 清空画布
     */
    handleClickClear() {
        const canvas = ReactDOM.findDOMNode(this.refs.myCanvas);
        canvas.height = canvas.height;
        this.setState({ accord: [] });
    }

    /**
     * 选择某一个工具
     */
    handleClickTool(index) {
        const { tools, shapes } = this.state;
        const toolArr = tools.map((tool, i) => {
            tool.selected = i === index;
            return tool;
        });
        const shapeArr = shapes.map((shape) => {
            shape.selected = false;
            return shape;
        });
        this.setState({
            tools: toolArr,
            shapes: shapeArr
        });
    }

    /**
     * 选择一个需要绘制的形状
     */
    handleClickShape(index) {
        const { tools, shapes } = this.state;
        const shapeArr = shapes.map((shape, i) => {
            shape.selected = i === index;
            return shape;
        });
        const toolArr = tools.map((tool) => {
            tool.selected = false;
            return tool;
        });
        this.setState({
            shapes: shapeArr,
            tools: toolArr
        });
    }

    /**
     * 选择了线条粗细
     */
    handleClickSize(index) {
        const { sizes } = this.state;
        const sizeArr = sizes.map((size, i) => {
            size.selected = i === index;
            return size;
        });
        this.setState({
            sizes: sizeArr
        });
    }

    /**
     * 选择了颜色
     */
    handleClickColor(index) {
        const { colors } = this.state;
        const colorArr = colors.map((color, i) => {
            color.selected = i === index;
            return color;
        });
        this.setState({
            colors: colorArr
        });
    }

    /**
     * 再次进入画布，鼠标左键没有松开的时候，不会和上次连接
     */
    handleCanvasMouseOut() {
        this.setState({
            flag: 0
        });
    }

    /**
     * 
     */
    handleCanvasMouseUp(e) {
        const canvas = ReactDOM.findDOMNode(this.refs.myCanvas);
        const ctx = canvas.getContext('2d');
        const { startX, startY, temp, colors, accord } = this.state;
        const upX = e.pageX - canvas.offsetLeft;
        const upY = e.pageY - canvas.offsetTop;
        
        temp.up.push(upX, upY);
        this.setState({
            flag: 0
        });
        const { tool, size, shape, color } = this.getCurrentPicProps();
        const col = colors[color].color;
        const lineWidths = size * 2 + 1;
        
        if (tool === 4) {
            var textValue = window.prompt('请在这里输入文字');
            textValue = textValue === null ? '' : textValue;
            temp.text.push(textValue);
            drawText(ctx, startX, startY, col, textValue);
        }
        accord.push(temp);
        const temp_d = { //存存储某一次鼠标点击到释放的坐标
            'tool': tool,
            'shape': shape,
            'line': lineWidths,
            'colors': col,
            'down': [],
            'move': [],
            'up': [],
            'text': []
        };
        this.setState({
            accord,
            temp: temp_d
        });
    }

    /**
     * 点击之后再画布上移动
     */
    handleCanvasMouseMove(e) {
        const canvas = ReactDOM.findDOMNode(this.refs.myCanvas);
        const ctx = canvas.getContext('2d');
        let { startX, startY, moveX, moveY, flag, temp, colors, accord } = this.state;
		moveX = e.pageX - canvas.offsetLeft;
        moveY = e.pageY - canvas.offsetTop;
        const { tool, size, color, shape } = this.getCurrentPicProps();
        const lineWidths = size * 2 + 1;
        const col = colors[color].color;
        if (flag) {
            temp.move.push([moveX, moveY]);
			switch (tool) {
            case 0: //画笔
				ctx.lineTo(moveX, moveY);
				ctx.lineWidth = lineWidths;
				ctx.strokeStyle = col;
				ctx.stroke();
				ctx.restore();
				break;
            case 1: //橡皮
				ctx.lineTo(moveX, moveY);
				ctx.lineWidth = lineWidths;
				ctx.strokeStyle = "#fff";
				ctx.stroke();
				ctx.restore();
                break;
            default:
                break;
            }
            switch (shape) {
                case 0: //直线
                    ctx.clearRect(0, 0, 880, 400);
                    this.againDraw(accord);
                    drawLine(ctx, startX, startY, moveX, moveY, lineWidths, col);
                    break;
                case 1: //路径圆
                    ctx.clearRect(0, 0, 880, 400);
                    this.againDraw(accord);
                    drawCircle(ctx, startX, startY, moveX, moveY, lineWidths, col);
                    break;
                case 2: //路径长方形
                    ctx.clearRect(0, 0, 880, 400);
                    this.againDraw(accord);
                    drawRect(ctx, startX, startY, moveX, moveY, lineWidths, col);
                    break;
                case 3: //路径三角形
                    ctx.clearRect(0, 0, 880, 400);
                    this.againDraw(accord);
                    drawTriangle(ctx, startX, startY, moveX, moveY, lineWidths, col);
                    break;
                case 4: //填充圆
                    ctx.clearRect(0, 0, 880, 400);
                    this.againDraw(accord);
                    fillCircle(ctx, startX, startY, moveX, moveY, lineWidths, col);
                    break;
                case 5: //填充矩形
                    ctx.clearRect(0, 0, 880, 400);
                    this.againDraw(accord);
                    fillRect(ctx, startX, startY, moveX, moveY, lineWidths, col);
                    break;
                default:
                    break;
                }
		}
    }

    /**
     * 当鼠标点下了画布
     */
    handleCanvasMouseDown(e) {
        const canvas = ReactDOM.findDOMNode(this.refs.myCanvas);
        const ctx = canvas.getContext('2d');
        let { startX, startY, moveX, colors } = this.state;
        const { tool, size, color, shape } = this.getCurrentPicProps();
        let temp = { //存存储某一次鼠标点击到释放的坐标
            'tool': tool,
            'shape': shape,
            'line': size * 2 + 1,
            'colors': colors[color].color,
            'down': [],
            'move': [],
            'up': [],
            'text': []
        };
		startX = e.pageX - canvas.offsetLeft;
        startY = e.pageY - canvas.offsetTop;
        temp.down.push(startX, startY);
        this.setState({
            startX,
            startY,
            flag : 1,
            temp
        });
		switch (tool) {
		case 0:
			ctx.save();
			ctx.beginPath();
			ctx.moveTo(startX, startY);
			break;
		case 1:
			ctx.save();
			ctx.beginPath();
			ctx.moveTo(startX, startY);
			break;
		case 2: //喷漆
			ctx.fillStyle = colors[color].color;
			ctx.fillRect(0, 0, 880, 400);
			break;
		case 3:
			var obj = ctx.getImageData(moveX, moveX, 1, 1); //吸管
			alert('色值为：rgba(' + obj.data + ')');
            break;
        default:
            break;
		}
    }
    /**
     * 获取画笔设置
     */
    getCurrentPicProps() {
        const { tools } = this.state;
        let tool = -1;
        tools.forEach((item, index) => {
            if (item.selected) tool = index;
        });

        const { sizes } = this.state;
        let size;
        sizes.forEach((item, index) => {
            if (item.selected) size = index;
        });

        const { shapes } = this.state;
        let shape = -1;
        shapes.forEach((item, index) => {
            if (item.selected) shape = index;
        });

        const { colors } = this.state;
        let color;
        colors.forEach((item, index) => {
            if (item.selected) color = index;
        });

        return {
            tool,
            size,
            color,
            shape
        }
    }
    /**
     * 根据储存的点重新画线
     */
    againDraw(storData) {
        const canvas = ReactDOM.findDOMNode(this.refs.myCanvas);
        const ctx = canvas.getContext('2d');
        for (let i = 0; i < storData.length; i++) {
            switch (storData[i].tool) {
            case 0:
                ctx.save();
                ctx.beginPath();
                ctx.moveTo(storData[i].down[0], storData[i].down[1]);
                for (let j = 0; j < storData[i].move.length; j++) {
                    ctx.lineTo(storData[i].move[j][0], storData[i].move[j][1]);
                }
                ctx.lineWidth = storData[i].line;
                ctx.strokeStyle = storData[i].colors;
                ctx.stroke();
                ctx.restore();
                break;
            case 1:
                ctx.save();
                ctx.beginPath();
                ctx.moveTo(storData[i].down[0], storData[i].down[1]);
                for (let j = 0; j < storData[i].move.length; j++) {
                    ctx.lineTo(storData[i].move[j][0], storData[i].move[j][1]);
                }
                ctx.lineWidth = storData[i].line;
                ctx.strokeStyle = '#fff';
                ctx.stroke();
                ctx.restore();
                break;
            case 2:
                ctx.fillStyle = storData[i].colors;
                ctx.fillRect(0, 0, 880, 400);
                break;
            case 4:
                drawText(ctx, storData[i].down[0], storData[i].down[1], storData[i].colors, storData[i].text[0]);
                break;
            default:
                break;
            }
        switch (storData[i].shape) {
            case 0:
                drawLine(ctx, storData[i].down[0], storData[i].down[1], storData[i].up[0], storData[i].up[1], storData[i].line, storData[i].colors);
                break;
            case 1:
                drawCircle(ctx, storData[i].down[0], storData[i].down[1], storData[i].up[0], storData[i].up[1], storData[i].line, storData[i].colors);
                break;
            case 2:
                drawRect(ctx, storData[i].down[0], storData[i].down[1], storData[i].up[0], storData[i].up[1], storData[i].line, storData[i].colors);
                break;
            case 3:
                drawTriangle(ctx, storData[i].down[0], storData[i].down[1], storData[i].up[0], storData[i].up[1], storData[i].line, storData[i].colors);
                break;
            case 4:
                fillCircle(ctx, storData[i].down[0], storData[i].down[1], storData[i].up[0], storData[i].up[1], storData[i].line, storData[i].colors);
                break;
            case 5:
                fillRect(ctx, storData[i].down[0], storData[i].down[1], storData[i].up[0], storData[i].up[1], storData[i].line, storData[i].colors);
                break;
            default:
                break;
            }
        }
    }

    render() {
        const { tools, shapes, sizes, colors } = this.state;

        const ToolArr = tools.map((tool, index) => <Tool key={tool.id} {...tool} onClick={this.handleClickTool} index={index}/>); 
        const ShapeArr = shapes.map((shape, index) => <Shape key={shape.id} {...shape} onClick={this.handleClickShape} index={index}/>)
        const SizeArr = sizes.map((size, index) => <Size key={size.id} {...size} onClick={this.handleClickSize} index={index}/>);
        const ColorArr = colors.map((color, index) => <Color key={color.id} {...color} onClick={this.handleClickColor} index={index}/>);

        return (
        <div>
            <div id="content">
                <ul id="tool">
                    <li>
                        <h3>图像</h3><hr/>
                        <ul id="image">
                            <li id="saveimg">
                                <button onClick={this.handleClickSave}>保存图片</button>
                            </li>
                            <li id="clearimg">
                                <button onClick={this.handleClickClear}>清空画板</button>
                            </li>
                        </ul>
                    </li>
                    <li>
                        <h3>工具</h3><hr/>
                        <ul id="tools">
                            { ToolArr }
                        </ul>
                    </li>
                    <li>
                        <h3>形状</h3>
                        <ul id="shape">
                            { ShapeArr }
				        </ul>
                    </li>
                    <li>
                        <h3>线宽</h3>
                        <ul id="size">
                            {SizeArr}
				        </ul>
                    </li>
                    <li>
                        <h3>颜色</h3>
                        <ul id="color">
                            {ColorArr}
                        </ul>
                    </li>
                </ul>
                <canvas id="canvas" ref="myCanvas" 
                width='880'
                height='400'
                onMouseMove={this.handleCanvasMouseMove} 
                onMouseUp={this.handleCanvasMouseUp} 
                onMouseDown={this.handleCanvasMouseDown}
                onMouseOut={this.handleCanvasMouseOut}
                >您的浏览器不支持</canvas>
            </div>
        </div>)
        
    }
}

export default MyDraw;